Popular Searches
Popular Course Categories
Popular Courses

Applying Access Control and Static Members in Java Programs

Applying Access Control and Static Members in Java Programs

Access Modifiers, Static Members, and Final Keyword

Applying Access Control and Static Members in Java Programs

Course: Core Java Training

Topic: Applying Access Control and Static Members in Java Programs

Course Link: Core Java Training Course

Demo Link: Register for a Course Demo

Website: JustAcademy


1. Introduction

Access control and static members are important concepts in Java object-oriented programming. Access control determines which classes can access fields, methods, constructors, and other class members. Static members belong to a class rather than to individual objects, making them useful for shared data, utility methods, and class-level operations.

When these concepts are used together, developers can create programs that are organized, reusable, secure against accidental misuse, and easier to maintain. For example, a banking application can keep an account balance private, provide public methods for accessing it safely, and use a static field to track the number of accounts created.

2. Learning Objectives

  • Understand access control and its importance in Java.
  • Learn the four member access levels: public, private, protected, and package-private.
  • Understand the difference between static and instance members.
  • Declare and access static variables and methods correctly.
  • Combine access modifiers with static members.
  • Use encapsulation to protect data.
  • Understand static constants, utility methods, and shared counters.
  • Identify common errors and follow Java programming best practices.

3. What Is Access Control in Java?

Access control determines where a class member can be accessed from. Java uses access modifiers to control visibility and support encapsulation, which means hiding internal implementation details and exposing only the operations that other parts of a program need.

Java provides four access levels for class members:

  • public: Accessible wherever the declaring type and member are accessible.
  • private: Accessible within the declaring top-level class, including its nested code where applicable.
  • protected: Accessible within the same package and, subject to Java's protected-access rules, from subclasses in other packages.
  • Package-private (default): Accessible within the same package when no access modifier is specified.

4. Understanding the public Access Modifier

The public modifier allows a member to be accessed from other classes wherever the declaring class or interface is accessible.

Example

class Student {
    public String name = "Aarav";

    public void displayName() {
        System.out.println("Student Name: " + name);
    }
}

public class PublicDemo {
    public static void main(String[] args) {
        Student student = new Student();

        System.out.println(student.name);
        student.displayName();
    }
}

Output

Aarav
Student Name: Aarav

Explanation: The name field and displayName() method are public, so the PublicDemo class can access them. In production applications, fields are usually kept private and exposed through suitable methods rather than made public directly.

5. Understanding the private Access Modifier

The private modifier restricts access to the declaring top-level class and its nested code. Other unrelated classes cannot directly access a private field or method.

Example

class BankAccount {
    private double balance = 5000.0;

    public double getBalance() {
        return balance;
    }
}

public class PrivateDemo {
    public static void main(String[] args) {
        BankAccount account = new BankAccount();

        System.out.println("Balance: " + account.getBalance());
    }
}

Output

Balance: 5000.0

Explanation: The balance field is private, so it cannot be accessed directly from PrivateDemo. The public getter provides controlled read access.

The following statement would cause a compilation error because the field is private:

// System.out.println(account.balance);

6. Understanding the protected Access Modifier

The protected modifier permits access from classes in the same package. It also permits access through inheritance in subclasses outside the package, subject to Java's protected-access restrictions.

Example

class Employee {
    protected String department = "Development";
}

class Developer extends Employee {
    public void displayDepartment() {
        System.out.println("Department: " + department);
    }
}

public class ProtectedDemo {
    public static void main(String[] args) {
        Developer developer = new Developer();
        developer.displayDepartment();
    }
}

Output

Department: Development

Explanation: The Developer class inherits from Employee and can access the protected field in this example. When subclasses are in different packages, protected access follows specific rules; it does not grant unrestricted access to the member through every superclass object reference.

7. Understanding Package-Private Access

When a field, method, constructor, or top-level class has no explicit access modifier, it generally receives package-private access. It can be accessed from other classes in the same package but not directly from unrelated classes in different packages.

Example

class Calculator {
    int add(int a, int b) {
        return a + b;
    }
}

public class DefaultAccessDemo {
    public static void main(String[] args) {
        Calculator calculator = new Calculator();

        System.out.println(calculator.add(10, 20));
    }
}

Output

30

Explanation: The Calculator class and its add() method have package-private access. The example works because both classes are in the same package.

8. Comparison of Java Access Modifiers

Access Level Same Class Same Package Subclass in Another Package Unrelated Class in Another Package
public Yes Yes Yes, if the type is accessible Yes, if the type is accessible
protected Yes Yes Yes, under protected-access rules No
Package-private Yes Yes No, unless it is also in the same package No
private Yes No No direct access No direct access

Note: Access to a member also depends on the accessibility of its declaring type and, in modular applications, the applicable module rules. A top-level class can be declared public or package-private; it cannot be declared private or protected.

9. What Are Static Members in Java?

The static keyword declares a member that belongs to the class rather than to each individual object. Static members can be used without creating an instance of the class, provided the class is accessible and has been initialized as required.

Common static members include:

  • Static variables or class variables.
  • Static methods or class methods.
  • Static initialization blocks.
  • Static nested classes.

10. Static Variables

A static variable is shared by all instances of a class. Each object has its own instance variables, but all objects of the same class share the same static field.

Example: Counting Objects

class Student {
    String name;
    static int studentCount = 0;

    Student(String studentName) {
        name = studentName;
        studentCount++;
    }
}

public class StaticVariableDemo {
    public static void main(String[] args) {
        new Student("Aarav");
        new Student("Meera");
        new Student("Kabir");

        System.out.println("Total Students: " + Student.studentCount);
    }
}

Output

Total Students: 3

Explanation: Each constructor increments the shared studentCount variable. After three objects have been created, the shared counter contains 3.

Using Student.studentCount makes it clear that the variable belongs to the class.

11. Static Methods

A static method belongs to the class and can be called using the class name. It is useful for operations that do not require the state of a particular object.

Example

public class MathUtility {
    public static int square(int number) {
        return number * number;
    }

    public static void main(String[] args) {
        int result = MathUtility.square(6);

        System.out.println("Square: " + result);
    }
}

Output

Square: 36

Explanation: The square() method is static, so it can be called directly with MathUtility.square(6) without creating a MathUtility object.

12. Static Methods and Instance Members

A static method does not have an implicit this reference because it is associated with the class rather than with a particular object. Therefore, it cannot directly access instance variables or call instance methods without an object reference.

Correct Example

public class Employee {
    String name = "Meera";
    static String company = "Tech Solutions";

    public void displayEmployee() {
        System.out.println(name);
        System.out.println(company);
    }

    public static void displayCompany() {
        System.out.println(company);
    }

    public static void main(String[] args) {
        Employee employee = new Employee();

        Employee.displayCompany();
        employee.displayEmployee();
    }
}

Output

Tech Solutions
Meera
Tech Solutions

Explanation: The static method accesses the static field company directly. The instance method accesses both the object's name field and the shared company field.

Incorrect Example

class Example {
    int number = 10;

    static void display() {
        // System.out.println(number); // Compilation error
    }
}

The static method cannot directly access the instance field number. It needs an object reference, such as Example obj = new Example(); followed by System.out.println(obj.number); from a context where that field is accessible.

13. Combining Access Modifiers with Static Members

Access modifiers can control who can use static fields and methods. The static keyword determines membership, while the access modifier determines visibility.

Declaration Meaning
public static int count; A class-level variable accessible wherever the declaring type and member are accessible.
private static int count; A class-level variable accessible only within its declaring top-level class and nested code where applicable.
protected static void show() A class-level method accessible within the package and through qualifying subclass access in other packages.
static void calculate() A package-private static method accessible within the same package.

14. Example: Private Static Variable with Public Static Methods

This design keeps shared data private while providing controlled methods to read and update it.

public class VisitorCounter {
    private static int count = 0;

    public static void recordVisit() {
        count++;
    }

    public static int getCount() {
        return count;
    }

    public static void main(String[] args) {
        VisitorCounter.recordVisit();
        VisitorCounter.recordVisit();
        VisitorCounter.recordVisit();

        System.out.println("Visits: " + VisitorCounter.getCount());
    }
}

Output

Visits: 3

Explanation: The count variable is private and static. External code cannot change it directly, but it can call public static methods that provide controlled access.

15. Static Constants Using static final

The combination of static and final is commonly used to declare class-level constants. The static keyword associates the field with the class, while final prevents reassignment after the field has been initialized.

Example

public class AppConfig {
    public static final int MAX_LOGIN_ATTEMPTS = 5;
    public static final String APP_NAME = "Student Portal";

    public static void main(String[] args) {
        System.out.println(AppConfig.APP_NAME);
        System.out.println(AppConfig.MAX_LOGIN_ATTEMPTS);
    }
}

Output

Student Portal
5

Explanation: Both fields are static constants and can be accessed using the class name. By convention, constant names are written in uppercase letters with underscores between words.

Important: A final reference to a mutable object does not make the object itself immutable. For shared public constants, prefer immutable values or carefully designed unmodifiable objects.

16. Static Initialization Blocks

A static initialization block performs class-level initialization that requires multiple statements. It executes during class initialization, before the class's initialization completes.

Example

public class Application {
    static int initialValue;

    static {
        int base = 20;
        int multiplier = 3;
        initialValue = base * multiplier;

        System.out.println("Static initialization completed");
    }

    public static void main(String[] args) {
        System.out.println("Initial Value: " + initialValue);
    }
}

Output

Static initialization completed
Initial Value: 60

Explanation: The static block calculates and assigns the value before the main method uses the initialized field.

17. Static Members and Inheritance

Static methods are associated with classes rather than individual objects. A subclass may declare a static method with a compatible signature that hides an accessible static method from its superclass. This is called method hiding, not method overriding.

Example

class Parent {
    static void display() {
        System.out.println("Parent static method");
    }
}

class Child extends Parent {
    static void display() {
        System.out.println("Child static method");
    }
}

public class StaticInheritanceDemo {
    public static void main(String[] args) {
        Parent.display();
        Child.display();

        Parent reference = new Child();
        reference.display();
    }
}

Output

Parent static method
Child static method
Parent static method

Explanation: Static method calls are resolved using the compile-time type used to qualify the method. The reference variable is declared as Parent, so reference.display() calls the parent static method even though it refers to a Child object.

Best practice: Call static methods using the class name rather than an object reference to make the intended behavior clear.

18. Static Nested Classes

A static nested class is declared inside another class using the static keyword. Unlike a non-static inner class, it does not require an instance of the enclosing class to be created.

Example

public class University {
    static String universityName = "Central University";

    static class Department {
        void display() {
            System.out.println(universityName);
        }
    }

    public static void main(String[] args) {
        University.Department department =
            new University.Department();

        department.display();
    }
}

Output

Central University

Explanation: The nested Department class can be instantiated using University.Department without first creating a University object. It can access the enclosing class's accessible static members directly.

19. Practical Example: Employee Management

The following program combines private instance fields, public methods, a private static counter, and a public static accessor to demonstrate access control and static members in a practical scenario.

public class Employee {
    private int employeeId;
    private String employeeName;
    private static int totalEmployees = 0;

    public Employee(String name) {
        employeeName = name;
        totalEmployees++;
        employeeId = totalEmployees;
    }

    public int getEmployeeId() {
        return employeeId;
    }

    public String getEmployeeName() {
        return employeeName;
    }

    public static int getTotalEmployees() {
        return totalEmployees;
    }

    public void displayDetails() {
        System.out.println("ID: " + employeeId);
        System.out.println("Name: " + employeeName);
    }

    public static void main(String[] args) {
        Employee e1 = new Employee("Aarav");
        Employee e2 = new Employee("Meera");

        e1.displayDetails();
        e2.displayDetails();

        System.out.println(
            "Total Employees: " + Employee.getTotalEmployees()
        );
    }
}

Output

ID: 1
Name: Aarav
ID: 2
Name: Meera
Total Employees: 2

Explanation

  • employeeId and employeeName are private instance fields.
  • totalEmployees is a private static field shared by all employees.
  • The constructor increments the shared counter and assigns an ID.
  • Public getter methods provide controlled access to private fields.
  • The static method getTotalEmployees() returns the shared employee count without requiring an object.

20. Common Mistakes to Avoid

  • Making every field public: This exposes internal state and allows uncontrolled modifications.
  • Accessing instance members directly from a static method: Use an object reference when an instance member is required.
  • Assuming static variables belong to each object: Static variables are shared by instances of the same class definition.
  • Calling static methods through object references: This is legal in many cases but obscures the fact that the method belongs to the class.
  • Assuming protected means accessible everywhere: Protected access outside the package is subject to subclass-access rules.
  • Confusing method hiding with overriding: Static methods are hidden rather than dynamically overridden.
  • Exposing mutable static state: Shared mutable fields can cause unexpected interactions between unrelated parts of a program.
  • Using static methods for object-specific behavior: Use instance methods when behavior depends on the state of a particular object.
  • Assuming final makes a referenced object immutable: A final reference cannot be reassigned, but its referenced object may still be mutable.

21. Best Practices

  • Use private for fields unless broader visibility is genuinely necessary.
  • Expose necessary operations through public methods with suitable validation.
  • Use static fields only for state that genuinely belongs to the class and is shared among its instances.
  • Prefer private static final for internal constants.
  • Use public static final for constants intended to be part of a public API, choosing immutable values where possible.
  • Use static methods for utility operations that do not depend on an object's state.
  • Prefer class-name access, such as MathUtility.square(5), for static methods and fields.
  • Avoid unnecessary global mutable state, particularly in multithreaded programs.
  • Use the most restrictive access level that meets the program's requirements.
  • Keep the public API small and clearly documented.

22. Practice Exercises

  1. Create a class with a private field and public getter and setter methods.
  2. Create a static counter that tracks how many objects have been created.
  3. Write a utility class containing static methods for addition, subtraction, multiplication, and division.
  4. Declare a public static final constant representing the maximum number of login attempts.
  5. Create a class with a protected field and access it from a subclass.
  6. Create two classes in the same package and demonstrate package-private access.
  7. Write a class with a private static variable and public static methods for reading and updating it.
  8. Create a parent and child class with static methods of the same signature and demonstrate method hiding.
  9. Build a simple employee management program using private instance fields and a static employee counter.
  10. Identify which declarations in a sample program should be static, instance-specific, public, or private, and explain your choices.

23. Interview Questions and Answers

Q1. What is access control in Java?

Access control determines where classes, fields, methods, and constructors can be accessed. Java uses public, protected, private, and package-private access levels.

Q2. What is the difference between private and public?

A private member is accessible within its declaring top-level class and its nested code where applicable. A public member can be accessed wherever its declaring type and the member are accessible.

Q3. What is package-private access?

Package-private access applies when no access modifier is specified. The member can be accessed from classes in the same package.

Q4. What does the static keyword mean?

The static keyword declares a class-level member that is associated with the class rather than with each individual object.

Q5. Can a static method access an instance variable directly?

No. A static method has no implicit object reference. It must use an appropriate object reference to access an instance variable.

Q6. What is the difference between static and instance variables?

A static variable is shared by instances of the class. An instance variable belongs to an individual object, and each object has its own value.

Q7. Can static methods be overridden in Java?

No. Static methods are hidden by compatible static methods declared in subclasses. Method overriding applies to eligible instance methods.

Q8. Why should fields usually be private?

Private fields support encapsulation by preventing unrelated classes from changing internal state directly. Public methods can validate changes and preserve object invariants.

Q9. What is the purpose of static final?

It is commonly used for class-level constants. The static keyword associates the field with the class, and final prevents reassignment after initialization.

Q10. Can a constructor be static?

No. Constructors initialize objects and cannot be declared static. Static initialization blocks are used for class-level initialization.

Q11. Can a private static method be called from another class?

No. A private static method is accessible only within its declaring top-level class and its nested code where applicable.

Q12. Why should static methods usually be called with the class name?

Using the class name makes it clear that the method belongs to the class and does not depend on a particular object.

24. Quick Revision Checklist

  • public allows broad access when the declaring type is accessible.
  • private restricts access to the declaring class and its nested code where applicable.
  • protected allows same-package access and qualifying subclass access outside the package.
  • No access modifier means package-private access.
  • static associates a field or method with the class rather than an individual object.
  • Static variables are shared among instances of the same class definition.
  • Static methods cannot directly access instance members without an object reference.
  • static final is commonly used for constants.
  • Static methods are hidden, not overridden, by compatible subclass static methods.
  • Encapsulation helps protect internal state and reduce unintended changes.
  • Use class-name access for static fields and methods.

25. Conclusion

Applying access control and static members effectively is essential for developing well-structured Java programs. Access modifiers help control visibility, protect internal data, and define a class's public interface. Static variables and methods provide class-level functionality for shared information, utility operations, counters, and constants.

By combining private fields, appropriate public methods, carefully selected access levels, and well-designed static members, developers can build programs that are reusable, maintainable, and easier to understand. Always choose visibility based on actual requirements and avoid unnecessary shared mutable state.

Continue learning with the JustAcademy Core Java Training Course. You can also register for a course demo or visit the JustAcademy website for more information.

Previous Next
whatsapp